package org.itboys.core.service.mongo.front;

import org.apache.commons.lang.StringUtils;
import org.itboys.admin.entity.lasted.SystemUser;
import org.itboys.admin.service.lasted.SystemUserService;
import org.itboys.commons.ErrorException;
import org.itboys.commons.utils.encryption.Digests;
import org.itboys.commons.utils.image.ImageUtils;
import org.itboys.commons.utils.tools.ListUtil;
import org.itboys.core.common.ExceptionEnum;
import org.itboys.core.common.LoginTypeEnum;
import org.itboys.core.common.SundayCommonConstants;
import org.itboys.core.common.UserTypeEnum;
import org.itboys.core.dao.coupon.SundayCouponMapper;
import org.itboys.core.dao.coupon.SundayCouponRecordMapper;
import org.itboys.core.dao.wallet.SundayWalletMapper;
import org.itboys.core.dto.member.SundayMemberDTO;
import org.itboys.core.entity.mongo.SundayMember;
import org.itboys.core.entity.mysql.coupon.SundayCoupon;
import org.itboys.core.entity.mysql.coupon.SundayCouponExample;
import org.itboys.core.entity.mysql.coupon.record.SundayMemberCoupon;
import org.itboys.core.entity.mysql.wallet.SundayWallet;
import org.itboys.core.util.InviteCodeUtil;
import org.itboys.core.util.NameUtil;
import org.itboys.framework.resource.ResourceHolder;
import org.itboys.mongodb.core.MongoDataSource;
import org.itboys.mongodb.service.BaseMongoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Author：贾琦磊
 * @Date：2018/11/26
 * @Description：用户
 */
@Service
public class SundayFrontMemberService extends BaseMongoService<SundayMember> {
    @Resource(name = "mobileDs")
    private MongoDataSource sundayDataSource;
    @Autowired
    private ResourceHolder resourceHolder;
    @Autowired
    private SundayValidateCodeService codeService;
    @Autowired
    private SundayWalletMapper walletMapper;

    @Override
    protected MongoDataSource getMongoDataSource() {
        return sundayDataSource;
    }

    @Override
    protected Class<SundayMember> getEntityClass() {
        return SundayMember.class;
    }

    @Autowired
    private SundayCouponMapper couponMapper;
    @Autowired
    private SundayCouponRecordMapper relationMapper;
    @Autowired
    private SystemUserService userService;

    /**
     * 登录
     *
     * @param userType  用户类型
     * @param loginType 登录类型
     * @param unionId   关联id
     * @param nickName  昵称
     * @param image     头像
     * @param mobile    电话号码
     * @param password  用户密码
     * @param code      验证码
     * @return
     */
    public SundayMemberDTO login(Integer userType, Integer loginType, String unionId, String nickName, String image, String mobile, String password, String code) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("isDeleted", SundayCommonConstants.NO);
        if (userType.equals(UserTypeEnum.SUPPLIER.getCode())) {
            param.put("mobile", mobile);
            //param.put("userType",UserTypeEnum.SUPPLIER.getCode());
            List<SundayMember> members = super.list(param);
            //验证账号
            if (!ListUtil.isNotNull(members)) {
                throw new ErrorException(ExceptionEnum.USER_NONENTITY.getValue());
            }
            SundayMember member = members.get(0);
            //验证密码
            if (member.getPassword().equals(Digests.md5(password))) {
                return packageSingleDto(member);
            }
            throw new ErrorException(ExceptionEnum.PASSWORD_ERROR.getValue());
        } else if (userType.equals(UserTypeEnum.LEASE.getCode())) {
            if (LoginTypeEnum.MOBILE.getCode().equals(loginType)) {
                codeService.checkValidateCode(mobile, code);
                param.put("mobile", mobile);
            } else if (LoginTypeEnum.WEIXIN.getCode().equals(loginType)) {
                param.put("weixinUnionId", unionId);
            } else if (LoginTypeEnum.QQ.getCode().equals(loginType)) {
                param.put("qqUnionId", unionId);
            } else if (LoginTypeEnum.ALIPAY.getCode().equals(loginType)) {
                param.put("alipayUnionId", unionId);
            } else {
                throw new ErrorException(ExceptionEnum.LOGIN_TYPE_EXCEPTION.getValue());
            }
            //Integer[] userTypes = {UserTypeEnum.COMPANY.getCode(), UserTypeEnum.LEASE.getCode()};
            //param.put("userType in", Arrays.asList(userTypes));
            List<SundayMember> oldMembers = super.list(param);
            if (ListUtil.isNotNull(oldMembers)) {
                SundayMember member = oldMembers.get(0);
                if (member == null) {
                    throw new ErrorException(ExceptionEnum.USER_NONENTITY.getValue());
                }
                return packageSingleDto(member);
            }
            //新建用户
            SundayMember member = new SundayMember();
            if (LoginTypeEnum.MOBILE.getCode().equals(loginType)) {
                member.setMobile(mobile);
            } else if (LoginTypeEnum.WEIXIN.getCode().equals(loginType)) {
                member.setWeixinUnionId(unionId);
            } else if (LoginTypeEnum.QQ.getCode().equals(loginType)) {
                member.setQqUnionId(unionId);
            } else if (LoginTypeEnum.ALIPAY.getCode().equals(loginType)) {
                member.setAlipayUnionId(unionId);
            }
            //默认注册时的用户类型为租赁端普通用户
            member.setThirdType(loginType);
            //获取mongo数据的下一个id转成一个六位的唯一字符串
            String idCode = InviteCodeUtil.idToCode(super.iDGeneratorService.getNextId(SundayMember.class.getName()));
            nickName = StringUtils.isEmpty(nickName) ? "用户-"+idCode : nickName;
            member.setNickName(nickName);
            member.setUserType(UserTypeEnum.LEASE.getCode());
            member.setStatus(SundayCommonConstants.USER_STATUS_INIT);
            if (StringUtils.isNotBlank(image)) {
                String random = String.valueOf(System.currentTimeMillis());
                //如果当前项目的上传文件目录下没有logo文件夹，请自行创建。此文件夹存放的是默认的头像和第三方登陆用户头像
                String savePath = resourceHolder.getStringValue("fileUploadPath") + "/logo/" + random + ".jpg";
                ImageUtils.buildImg(savePath, image);
                member.setImage("/logo/" + random + ".jpg");
            } else {
                member.setImage(NameUtil.getRandomLogo());
            }
            super.save(member);
            //给新用户注册一个钱包
            SundayWallet wallet = new SundayWallet(member.getId(), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
            walletMapper.insert(wallet);

            return packageSingleDto(member);
        }
        throw new ErrorException(ExceptionEnum.USER_TYPE_ERROR.getValue());
    }

    /**
     * 拼装单个dto
     *
     * @param member
     * @return
     */
    private SundayMemberDTO packageSingleDto(SundayMember member) {
        SundayMemberDTO dto = new SundayMemberDTO();
        BeanUtils.copyProperties(member, dto);
        dto.setImage(resourceHolder.getStringValue("imgRoot") + member.getImage());
        dto.setPermit(resourceHolder.getStringValue("imgRoot") + member.getPermit());
        return dto;
    }

    /**
     * 更新用户信息
     *
     * @param memberId
     * @param company
     * @param permit
     * @param image
     * @param mobile
     * @param code
     * @return
     */
    public SundayMemberDTO update(Long memberId, String company, String permit, String image, String mobile, String code) {
        SundayMember member = super.getById(memberId);
        if (company != null || permit != null) {
            member.setCompany(company);
            member.setPermit(permit);
            member.setStatus(SundayCommonConstants.USER_STATUS_INIT);
        }
        member.setImage(image);
        if (StringUtils.isNotEmpty(mobile) && StringUtils.isNotEmpty(code)) {
            codeService.checkValidateCode(mobile, code);
            Map<String, Object> param = new HashMap<>();
            param.put("isDeleted", SundayCommonConstants.NO);
            param.put("mobile", mobile);
            List<SundayMember> members = super.list(param);
            if (ListUtil.isNotNull(members)) {
                throw new ErrorException(ExceptionEnum.MOBILE_HAS_BEEN_REGISTERED.getValue());
            }
            member.setMobile(mobile);
        }
        super.updateExceptEmpty(memberId, member);
        return packageSingleDto(member);
    }

    public SundayMemberDTO findOne(Long id) {
        SundayMember member = super.getById(id);
        if (member != null) {
            return packageSingleDto(member);
        }
        return new SundayMemberDTO();
    }

    /**
     * 经销商忘记密码
     *
     * @param mobile
     * @param code
     * @param newPassword
     */
    public void forgetPWD(String mobile, String code, String newPassword) {
        codeService.checkValidateCode(mobile, code);
        Map<String, Object> param = new HashMap<>();
        param.put("isDeleted", SundayCommonConstants.NO);
        param.put("mobile", mobile);
        List<SundayMember> members = super.list(param);
        if (ListUtil.isNull(members)) throw new ErrorException(ExceptionEnum.USER_NONENTITY.getValue());
        SundayMember member = members.get(0);
        member.setPassword(Digests.md5(newPassword));
        super.updateExceptEmpty(member.getId(), member);
        SystemUser user = userService.findOne(mobile);
        userService.update(user.getId(),"password",Digests.md5(newPassword));
    }

    /**
     * 用户更改密码，已登录
     *
     * @param memberId
     * @param mobile
     * @param code
     * @param oldPassword
     * @param newPassword
     */
    public void updatePWD(Long memberId, String mobile, String code, String oldPassword, String newPassword) {
        SundayMember member = super.getById(memberId);
        if (member == null) throw new ErrorException(ExceptionEnum.USER_NONENTITY.getValue());
        if (!member.getMobile().equals(mobile)) {
            throw new ErrorException(ExceptionEnum.MOBILE_EQUAL_TXCEPTION.getValue());
        }
        codeService.checkValidateCode(mobile, code);
        if (!member.getPassword().equals(Digests.md5(oldPassword))) {
            throw new ErrorException(ExceptionEnum.PASSWORD_ERROR.getValue());
        }
        member.setPassword(Digests.md5(newPassword));
        super.updateExceptEmpty(member.getId(), member);
        SystemUser user = userService.findOne(mobile);
        userService.update(user.getId(),"password",Digests.md5(newPassword));
    }

    /**
     * 更新用户已接收，分发邀请人优惠券
     *
     * @param memberId
     * @param code
     */
    public void invite(Long memberId, String code) {
        super.update(memberId, "accepted", SundayCommonConstants.YES);
        Long id = InviteCodeUtil.codeToId(code);
        SundayCouponExample example = new SundayCouponExample();
        example.createCriteria().andIsDeletedEqualTo(SundayCommonConstants.NO)
                .andTypeEqualTo(SundayCommonConstants.COUPON_TYPE_INVITE)
                .andEndDateGreaterThan(new Date());
        List<SundayCoupon> coupons = couponMapper.selectByExample(example);
        if (ListUtil.isNull(coupons)) return;
        List<SundayMemberCoupon> memberCoupons = new ArrayList<>();
        for (SundayCoupon c : coupons
                ) {
            //用户领取优惠券
            SundayMemberCoupon memberCoupon = new SundayMemberCoupon();
            memberCoupon.setMemberId(id);
            memberCoupon.setUsed(SundayCommonConstants.NO);
            memberCoupon.setCouponId(c.getId());
            memberCoupon.setMoney(c.getMoney());
            memberCoupon.setType(c.getType());
            memberCoupons.add(memberCoupon);
        }
        relationMapper.batchInsert(memberCoupons);
    }

}
